﻿using System;
using System.Collections.Generic;
using Se.Framework.Common;

namespace Se.Framework.Test
{
    public class TestObjectRegistry : IObjectRegistry
    {
        private Dictionary<string, object> RegisteredInstances = new Dictionary<string, object>();

        public T Resolve<T>() where T : class
        {
            return (T)Resolve(typeof(T));
        }

        public T Resolve<T>(string name) where T : class
        {
            return (T)Resolve(typeof(T), name);
        }

        public object Resolve(Type type, string name)
        {
            if (!IsRegistered(type, name))
                throw new TestObjectRegistryTypeNotRegistered(type, name);
            return RegisteredInstances[string.Format("{0}.{1}", type.FullName, name)];
        }

        public object Resolve(Type type)
        {
            if (!IsRegistered(type))
                throw new TestObjectRegistryTypeNotRegistered(type);
            return RegisteredInstances[type.FullName];
        }

        public IEnumerable<object> ResolveAll(Type type)
        {
            // TODO: Implement this method
            throw new NotImplementedException();
        }

        public void RegisterInstance(Type typeFrom, object instanceTo)
        {
            RegisteredInstances[typeFrom.FullName] = instanceTo;
        }

        public void RegisterInstance(Type typeFrom, string name, object instanceTo)
        {
            RegisteredInstances[string.Format("{0}.{1}", typeFrom.FullName, name)] = instanceTo;
        }

        public void RegisterType(Type typeFrom)
        {
            // TODO: Implement this method
            throw new NotImplementedException();
        }

        public void RegisterType(Type typeFrom, Type typeTo)
        {
            // TODO: Implement this method
            throw new NotImplementedException();
        }

        public void RegisterType<TFrom>()
        {
            this.RegisterType(typeof(TFrom));
        }

        public void RegisterType<TFrom, TTo>()
        {
            // TODO: Implement this method
            throw new NotImplementedException();
        }

        public void Reset()
        {
            RegisteredInstances.Clear();
        }

        public void Clean(object instance)
        {
            RegisteredInstances.Remove(instance.GetType().FullName);
        }

        public bool IsRegistered(Type type, string name)
        {
            return RegisteredInstances.ContainsKey(string.Format("{0}.{1}", type.FullName, name));
        }

        public bool IsRegistered(Type type)
        {
            return RegisteredInstances.ContainsKey(type.FullName);
        }

        public bool IsRegistered<T>() where T : class
        {
            return IsRegistered(typeof(T));
        }

        public bool IsRegistered<T>(string name) where T : class
        {
            return IsRegistered(typeof(T), name);
        }

        public Lazy<object> ResolveLazy(Type type)
        {
            return new Lazy<object>(() => Resolve(type));
        }

        public Lazy<object> ResolveLazy(Type type, string name)
        {
            return new Lazy<object>(() => Resolve(type, name));
        }

        public Lazy<T> ResolveLazy<T>() where T : class
        {
            return new Lazy<T>(() => Resolve<T>());
        }

        public Lazy<T> ResolveLazy<T>(string name) where T : class
        {
            return new Lazy<T>(() => Resolve<T>(name));
        }
    }
}